`define ALL_and_INST 	(inst_and | inst_andi)
`define ALL_or_INST       (inst_or | inst_ori )
`define ALL_xor_INST 		(inst_xor | inst_xori )
`define ALL_add_INST     (inst_add  | inst_addi | inst_addu | inst_addiu)
`define ALL_sub_INST 	  (inst_sub | inst_subu )
`define ALL_slt_INST 		(inst_slt | inst_slti | inst_sltu | inst_sltiu)
`define ALL_jmp_INST	  (inst_j | inst_jal | inst_jr) 
`define ALL_bne_INST 	  (inst_beq | inst_bne)

`define ALL_ARITH_INST  (`ALL_add_INST | `ALL_sub_INST | `ALL_slt_INST )
`define ALL_LOGIC_INST (inst_and | inst_andi | inst_nor | inst_or | inst_ori | inst_xor | inst_xori)
`define ALL_SHIFT_INST  (inst_sll | inst_sllv | inst_sra | inst_srav | inst_srl | inst_srlv )
`define ALL_LMEM_INST (inst_lb | inst_lbu | inst_lh | inst_lhu | inst_lw )
`define ALL_SMEM_INST (inst_sb | inst_sh | inst_sw)
`define ALL_MEM_INST   (`ALL_LMEM_INST | `ALL_SMEM_INST) 
`define ALL_IMM_INST    ( inst_addi | inst_addiu | inst_slti | inst_sltiu | inst_andi | inst_lui | inst_ori | inst_xori )

module DCU_step2(
	input wire 				inst_add,
	input wire              inst_addi,
	input wire              inst_addu,
	input wire              inst_addiu,
	input wire              inst_sub,
	input wire 				inst_subu,
	input wire 				inst_slt,
	input wire 				inst_slti,
	input wire				inst_sltu,
	input wire				inst_sltiu,
	input wire				inst_mult,
	input wire				inst_multu,
	input wire              inst_div,
	input wire              inst_divu,
    input wire				inst_and,
	input wire 				inst_andi,
	input wire 				inst_lui ,
	input wire 				inst_nor ,
	input wire				inst_or,
	input wire 				inst_ori,
	input wire				inst_xor,
	input wire 				inst_xori,
	input wire 				inst_sll ,
	input wire              inst_sllv,
	input wire              inst_sra,
	input wire              inst_srav ,
	input wire              inst_srl ,
	input wire              inst_srlv ,
	input wire              inst_mfhi,
	input wire              inst_mflo,
	input wire              inst_mthi,
	input wire              inst_mtlo,
	input wire              inst_lb,
	input wire              inst_lbu,
	input wire              inst_lh,
	input wire              inst_lhu,
	input wire 				inst_lw,
    input wire 				inst_sb,
	input wire              inst_sh,
	input wire 				inst_sw,
	input wire 				inst_jal,
	input wire 				inst_j,
	input wire 				inst_jr,
	input wire 				inst_beq,
	input wire 				inst_bne,
	input wire              equ,
	
	output wire 		      whilo,
	output wire			      wreg,
	output wire[2:0] 		alutype,
	output wire[7:0]		aluop,
	output wire 		      shift,
	output wire			      rreg1,
	output wire 		      rreg2,
	output wire			      immsel,
	output wire 		      rtsel,
	output wire			      sext,
	output wire 		      upper,
	output wire 		      mreg,
	output wire 		      jal,
	output wire[1:0]        jtsel
);
assign equ_in = (inst_beq == 1) ? equ :
						  (inst_bne == 1) ? (~equ) : 1'b0;

assign rreg1 = inst_add  | inst_addi | inst_addu | inst_addiu | 
						inst_subu | inst_sub  | 
						inst_slt     | inst_slti   | inst_sltu    | inst_sltiu   | 
						inst_mult | inst_multu | inst_div   | inst_divu  |  
						inst_and | inst_andi | inst_nor | inst_or | inst_ori | inst_xor | inst_xori |
						inst_sllv | inst_srav | inst_srlv | 
						inst_beq | inst_bne |
						inst_jr |  //jalr
						inst_mthi | inst_mtlo | 
						inst_lb | inst_lbu | inst_lh | inst_lhu |  inst_lw | inst_sb | inst_sh | inst_sw ;

assign rreg2 = inst_add | inst_addi | inst_addu | inst_addiu | 
						inst_subu | inst_sub |
						inst_slt | inst_sltu |
						inst_mult | inst_multu  | inst_div   | inst_divu  |  
						inst_and | inst_lui | inst_nor | inst_or | inst_xor | 
						inst_sllv | inst_sll | inst_srav | inst_sra | inst_srlv | inst_srl | 
						inst_beq | inst_bne | 
						inst_sb | inst_sh |  inst_sw ;

//这里书上写的有问题。最后一个应该是 jal 而不是 jr
assign wreg  = inst_add | inst_addi | inst_addu | inst_addiu | 
						inst_subu | inst_sub |
						inst_slt | inst_slti | inst_sltu | inst_sltiu | 
						inst_and | inst_andi | inst_lui | inst_nor | inst_or | inst_ori | inst_xor | inst_xori |
						inst_sll | inst_sllv | inst_srav | inst_sra | inst_srl | inst_srlv |
						inst_mfhi | inst_mflo | 
						inst_lb | inst_lbu | inst_lh | inst_lhu | | inst_lw | 
						inst_jal; //jalr

assign whilo = inst_mult | inst_multu | inst_div | inst_divu ;

assign aluop[7] = inst_mfhi;
always @(*) begin

end
assign aluop[6:5] = (inst_mult  == 1 ) ? 2'b01 : 
								(inst_multu == 1) ? 2'b00 :
								(inst_div == 1)	?      2'b11 :
								(inst_divu == 1) ?    2'b10 : 2'b00 ;
assign aluop[4] = `ALL_xor_INST | inst_slt | inst_slti  | inst_lui;
assign aluop[3] = `ALL_and_INST | `ALL_or_INST | 
							 inst_sub | inst_subu |  inst_sltu | inst_sltiu | 
							 inst_sra   | inst_srav  | inst_srl | inst_srlv;

assign aluop[2] = inst_nor | `ALL_or_INST | `ALL_add_INST | `ALL_MEM_INST |
							inst_lui |
							 inst_sltu | inst_sltiu | inst_sll | inst_sllv | inst_srl | inst_srlv; 
// 逻辑指令 和 位移指令
assign aluop[1] =  `ALL_LOGIC_INST | `ALL_SHIFT_INST  | inst_lui ;
//逻辑指令 和 算数指令 
assign aluop[0] = `ALL_LOGIC_INST | `ALL_ARITH_INST | `ALL_MEM_INST |
							  inst_lui ;


//alutype[2] = shift + jump 
assign alutype[2] =`ALL_SHIFT_INST | inst_jal;
//alutype[1] = logic + move
assign alutype[1] = `ALL_LOGIC_INST | inst_mfhi | inst_mflo | inst_lui ;
//alutyep[0] = arith + move + jump + 访存 
assign alutype[0] = `ALL_ARITH_INST | `ALL_MEM_INST | inst_jal | inst_mfhi | inst_mflo ;

//是否使用 sa 字段
assign shift  = inst_sll | inst_sra | inst_srl ;
//是否是 i 型指令 (BEQ 和 BNE 不考虑)
assign immsel = `ALL_IMM_INST | `ALL_MEM_INST;
//是否要写入 rt 寄存器
assign rtsel     = `ALL_IMM_INST | `ALL_LMEM_INST ;
//是否启用符号拓展 (BEQ 和 BNE 不考虑)
assign sext  = inst_addi | inst_addiu | inst_slti | inst_sltiu | `ALL_MEM_INST ; 
//upper 只用于 lui 
assign upper  = inst_lui;
//是否要要从存储器中拿数据
assign mreg   = `ALL_LMEM_INST;


assign jal = inst_jal;
//这里书上写错了
assign jtsel[0] = inst_j  | inst_jal | (inst_beq & equ_in ) | (inst_bne & (~equ));
assign jtsel[1] = inst_jr | (inst_beq & equ_in) | (inst_bne & (~equ));


endmodule